package com.beyondsoft.dtc.mobile.automation.impl.compatibility;

import com.beyondsoft.dtc.mobile.automation.base.*;
import com.beyondsoft.dtc.mobile.automation.model.ApkFile;
import com.beyondsoft.dtc.mobile.automation.model.Device;
import com.beyondsoft.dtc.mobile.automation.model.Task;
import com.beyondsoft.dtc.mobile.automation.model.TaskResult;
import com.beyondsoft.dtc.mobile.automation.redis.RedisClient;
import com.beyondsoft.dtc.mobile.automation.uiautomator.model.Coordinate;
import com.beyondsoft.dtc.mobile.automation.uiautomator.model.UiDumpModel;
import com.beyondsoft.dtc.mobile.automation.util.*;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by Robin on 3/11/2016.
 */
public class CompatibilityTestExecutor extends BaseExecutor implements Runnable {

    private final Logger logger = LoggerFactory
            .getLogger(CompatibilityTestExecutor.class);
    private final Jedis redis = RedisClient.getRedisClient().getJedis();
    private final int monkeyCount;
    private int monkeyCount1;
    private int flag = 1;
    private String adbUserName = "";
    private String adbPassword = "";
    private String needLoad = "";
    private List<String> picShot;
    private String packageName;
    private boolean beTraversal;
    private long beforeTime;
    private long afterTime;
    private boolean monkeyFinish = false;
    private int threshold = 40;//定义的UI检测时间，如果有需要，可以修改


    public CompatibilityTestExecutor(String taskId, String deviceRootPath,
                                     final AtomicInteger lock, ApkFile apkFile, Device device,
                                     String token, Task task) {
        super(taskId, deviceRootPath, lock, apkFile, device, token);
        taskResult.setTaskType(TaskType.TASK_COMPATIBILITY.getTaskName());
        adbUserName = task.getUserName();
        adbPassword = task.getPassword();
        needLoad = task.getNeedLoad();
        packageName = apkFile.getPackageName();
        taskResult.setMail(task.getMail());
        beTraversal = task.isBeTraversal();
        monkeyCount = task.getMonkeyNum();
    }

    @Override
    public void run() {
        logger.info(connectAddress + " start compatibility has running");
        openWifi();
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        boolean needUploadResult = false;
        openedActivity = new ArrayList<>();
        picShot = new ArrayList<>();
        try {
            taskResult.setAppDownload(AutomationResult.SUCCESS.getValue());

            if (!apkFile.isParsed()) {
                taskResult.setAppParse(AutomationResult.FAILURE.getValue());
                taskResult.setAppRunErrorDesc("parse apk file failure!");
                throw new BaseException(BaseException.ERROR_PARSE_APK_FAILD,
                        "parse apk file failure!");
            }
            taskResult.setAppParse(AutomationResult.SUCCESS.getValue());

            if (!device.isUSBDevice()) {
                if (!toggleToRemoteADBServer(connectAddress, true)) {
                    ExlFileUtil.saveInfo(taskId, connectAddress,
                            "is not accessible!");
                    taskResult.setAppRunErrorDesc("device " + connectAddress + " is not accessible!");
                    throw new BaseException(BaseException.ERROR_DEVICE_OFFLINE,
                            "device " + connectAddress + " is not accessible!");
                }
            }
            if (!checkDevice()) {
                taskResult.setAppInstall(AutomationResult.FAILURE.getValue());
                ExlFileUtil.saveInfo(taskId, connectAddress,
                        "device has offline");
                taskResult.setAppRunErrorDesc("device " + connectAddress
                        + " is offline!");
                throw new BaseException(BaseException.ERROR_DEVICE_OFFLINE,
                        "device " + connectAddress + " is offline!");
            }
            setVolumeTo0();
            clearDevice();
            sdkVersion = getSdkVersion();
            if (!unLockScreenCrazy()) {
                taskResult.setAppInstall(AutomationResult.FAILURE.getValue());
                ExlFileUtil.saveInfo(taskId, connectAddress,
                        "unlock screen failed");
                taskResult.setAppRunErrorDesc("device " + connectAddress
                        + " locked failed");
                throw new BaseException(BaseException.ERROR_DEVICE_OFFLINE,
                        "device " + connectAddress + " locked failed!");
            }
            doDialogCheckParalleled(false);
            logger.info(connectAddress + " is in home pager");
            needUploadResult = true;
            uninstallApk(false);
            logger.info(connectAddress + " uninstall ok");

            disableDeviceSettingScreen();

            installStopFlag.set(false);

            boolean ret = installApk();
            if (!ret) {
                installStopFlag.set(true);
                throw new BaseException(BaseException.ERROR_CAMMAND_FAILD,
                        "install failed!");
            }

            logger.info(connectAddress + " install ok");
            unLockScreenCrazy();

            // apk start
            ret = startApp(true);
            if (!ret) {
                installStopFlag.set(true);
                throw new BaseException(BaseException.ERROR_CAMMAND_FAILD,
                        "start failed!");
            }
            startMonitor();
            startAppFlag.set(true);
            long startWaitInterval = GlobalConfig.getInstance()
                    .getStartWaitTimeout();
            if (sdkVersion > 16) {
                startWaitInterval /= 2;
            }
            Thread.sleep(startWaitInterval);
            // sleep a while here to let app warm up.
            if (!openedActivity.contains(getCurrentActivityName())) {
                openedActivity.add(getCurrentActivityName());
            }
            doWizardPage();
            logger.info("stop wizardPage");
            if (!openedActivity.contains(getCurrentActivityName())) {
                openedActivity.add(getCurrentActivityName());
            }

            logger.error("needLoad  : 	" + needLoad);

            if (needLoad.contains("true")) {
                if (forceStop()) {
                    if (startApp(false)) {
                        Thread.sleep(10000L);
                        logger.info("登录截图");
                        takePicShot(picShot);
                        checkLogin();
                    }
                }
                Thread.sleep(10000L);
            }

            if (!openedActivity.contains(getCurrentActivityName())) {
                openedActivity.add(getCurrentActivityName());
            }

            LogCatManager logcatManager = LogCatManager.getInstance();
            logcatManager.start(deviceRootPath + "/check_ui_logcat.log");

            logger.info("开始UI测试");
            beforeTime = System.currentTimeMillis();
            if (beTraversal) {
                logger.info("start check allUI");
                checkAllUI();
                logger.info("stop check allUI");
            }
            logger.info("结束UI测试");
            logcatManager.stop();
            logger.info("compress image " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()));
            List<String> sameFiles = new ArrayList<>();
            for (int i = 0; i < picShot.size() - 1; i++) {
                String filesStart = "/code/apkTest/" + picShot.get(i);
                String filesEnd = "/code/apkTest/" + picShot.get(i + 1);
                int semblance = ImageCompress.compareImage(filesEnd, filesStart);
                if (semblance > 99) {
                    sameFiles.add(filesStart);
                }
            }
            if (sameFiles.size() > 0) {
                picShot.removeAll(sameFiles);
            }
            logger.info("compress image time" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()));


            clearClickBroadcast();
            setVolumeTo0();
            isGetScreenShot = true;
            startMonkeyTest.set(true);
            beforeTime = System.currentTimeMillis();
            logger.info("开始Monkey测试" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()));
            monkeyCount1 = monkeyCount;
            while (!monkeyFinish) {
                // apk run -- monkey
                monkeyTest(monkeyCount1);
                afterTime = System.currentTimeMillis();
                if ((afterTime - beforeTime) >= (monkeyCount * 300)) {
                    logger.info("1测试花了：" + (afterTime - beforeTime) / 1000);
                    monkeyFinish = true;
                } else {
                    logger.info("已经测试了：" + (afterTime - beforeTime) / 1000);
                    long restTimes = monkeyCount * 300 - (afterTime - beforeTime);
                    monkeyCount1 = (int) (restTimes * monkeyCount1 / (afterTime - beforeTime));
                    logger.info("还需要测试：" + monkeyCount1 + "次");
                }
            }
            logger.info("monkey总耗时：" + (afterTime - beforeTime) / 1000 + "秒");
            logger.info("结束Monkey测试" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()));
            stopFlag.set(true);
            openWifi();
            logger.debug(connectAddress + " {}", "start collection crash log");
            String runLog = deviceRootPath + "run_tmp.log";
            String runAppLog = deviceRootPath + "run_app.log";// app related log
            String exceptionLog = deviceRootPath + "exception.log";
            String crashLog = deviceRootPath + "crash.log";
            String anrLog = deviceRootPath + "traces.txt";

            collectAnrCrashExceptionLog(runLog, runAppLog, exceptionLog, crashLog, anrLog);

            try {
                appLog.setDeviceId(taskResult.getDeviceId());
                appLog.setTaskId(taskResult.getTaskId());
                appLog.setAppName(taskResult.getAppName());
                Gson gson = new Gson();
                String postPara = gson.toJson(appLog);
                logger.info(connectAddress + " applog:json:1"
                        + postPara.replace("\\t", "\n\t"));
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");// 设置日期格式
                String date = df.format(new Date());
                String anrKey = "JRX||ANR||" + date;
                logger.info("redis anrKey:" + postPara);
                redis.lpush(anrKey, postPara);
                logger.info(connectAddress + "	add anr to redis : " + postPara);
            } catch (Exception e) {
                logger.info(connectAddress + " send test log to server failed, error msg = [{}]",
                        e.getMessage(), e);
            }

            logger.info(connectAddress + " stoping  app");
            stopApp();
            logger.info(connectAddress + " stop app ok and start uninstall app");
            uninstallApk(true);
            logger.info(connectAddress + " uninstall app ok ");
            logger.info(connectAddress + " >> down testing with device: {}",
                    connectAddress);
        } catch (Exception e) {
            logger.error(connectAddress + e.getMessage(), e);

            if (taskResult.getAppInstall() == GlobalConstants.AutomationResult.SUCCESS.getValue()) {
                if (uninstallApk(false)) {
                    taskResult.setAppUninstall(GlobalConstants.AutomationResult.SUCCESS.getValue());
                }
            }

        }
        if (!device.isUSBDevice()) {
            try {
                toggleToRemoteADBServer(connectAddress, false);
            } catch (Exception e) {
                logger.error(connectAddress + e.getMessage(), e);
            }
        }

        taskResult.getScreenshots().addAll(0, picShot);

        // upload rest result to storage server.
        GlobalConfig globalConfig = GlobalConfig.getInstance();
        if (needUploadResult) {
            try {
                Thread.sleep(3000L);
            } catch (InterruptedException e1) {
                logger.error(e1.getMessage());
            }

            // 进行图片压缩
            List<String> pictureList = taskResult.getScreenshots();
            List<String> pictureListNew = new ArrayList<String>();
            try {
                for (int i = 0; i < pictureList.size(); i++) {
                    String path = removedPrefix;
                    String fileName = pictureList.get(i);
                    int lastFlag = fileName.lastIndexOf("/");

                    String toFileName = fileName.substring(0, lastFlag + 1)
                            + "dist_"
                            + fileName.substring(lastFlag + 1, fileName.length());

                    logger.info("imageCompress File name:" + toFileName);

                    float scale = 0.6f;
                    int width = 640;
                    int height = 960;
                    ImageCompress.imageCompress(path, fileName, toFileName, scale,
                            0.5f, width, height);
                    pictureListNew.add(toFileName);

                    String picPath = pictureList.get(i);
                    File f = new File(removedPrefix + picPath);
                    f.delete();
                }
            } catch (Exception e) {
                logger.error("imageCompress has an Exception 	" + e.getStackTrace());
            }
            logger.debug("pictureListNew:" + pictureListNew.toString());
            taskResult.setScreenshots(pictureListNew);


            try {
                String fileName = taskId + "-" + device.getSerialNumber()
                        + ".zip";
                String targetFile = "/tmp/" + fileName;
                String tmpParentPath = "/tmp/" + taskId + "-"
                        + device.getSerialNumber() + "-"
                        + System.currentTimeMillis();
                String tmpPath = tmpParentPath + "/" + taskId + "/";
                String iconPath = apkFile.getIconLocalFilePath();
                // all below's command is just want to zip focused device
                // related report files
                // but also keep folder tree inside zip file. (e.g.
                // Task123/Device456/)
                String[] command = {
                        "sh",
                        "-c",
                        "rm -rf " + tmpParentPath + " && rm -rf " + targetFile
                                + " && mkdir -p " + tmpPath + " && cp -r "
                                + deviceRootPath + " " + tmpPath + " ; cp "
                                + iconPath + " " + tmpPath + " ; cd "
                                + tmpParentPath + " && zip -r " + targetFile
                                + " " + taskId};

                ShellUtil.CommandResult commandResult = ShellUtil
                        .execCommand(command);
                if (!commandResult.isCommandSucceeded()) {
                    logger.error(connectAddress
                                    + " zip report files failed: {}",
                            commandResult.toString());
                } else {
                    String url = BaseController.STORAGE_URL
                            + globalConfig.getStorageCompatibilityUploadUrl();
                    logger.info(connectAddress
                                    + " Upload result files start,device: {},url: {}",
                            connectAddress, url);
                    String res = HttpUtil.fileUpload(url, targetFile, token);
                    logger.info(
                            connectAddress
                                    + " Upload result files done,device: {},url: {}, res: {}",
                            connectAddress, url, res);
                }

                command = new String[]{"sh", "-c",
                        "rm -rf " + tmpParentPath + " && rm -rf " + targetFile};
                ShellUtil.execCommand(command);
            } catch (Exception e) {
                logger.error(connectAddress
                                + " Upload test result files error: [{}]",
                        e.getMessage(), e);
            }
        }

        try {
            Thread.sleep(3000L);
            taskResult.setSign(token);
            Gson gson = new GsonBuilder()
                    .excludeFieldsWithoutExposeAnnotation().create();


            String postPara = gson.toJson(taskResult, TaskResult.class);
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");// 设置日期格式
            String date = df.format(new Date());
            String resultKey = "JRX||RESULT||" + date;
            logger.error("redis info" + postPara);
            redis.lpush(resultKey, postPara);

            logger.info(connectAddress + "	add info to redis : " + postPara);

        } catch (Exception e) {
            logger.info(connectAddress
                            + " send test feedback to server failed, error msg = [{}]",
                    e.getMessage(), e);
        }
        redis.close();
        System.exit(0);
    }

    private void monkeyTest(int monkeyTimes) {
        startMonkeyTest(GlobalConfig.getInstance()
                .getMonkeyTestRepeatInterval(), monkeyTimes == 0 ? GlobalConfig.getInstance()
                .getMonkeyTestRepeatCount() : monkeyTimes, GlobalConfig.getInstance()
                .getMonkeyTestPctTouch(), GlobalConfig.getInstance()
                .getMonkeyTestPctMotion(), GlobalConfig.getInstance()
                .getMonkeyTestPctAppSwitch(), GlobalConfig.getInstance()
                .getMonkeyTestPctSysKeys(), GlobalConfig.getInstance()
                .getMonkeyTestPctAnyEvent());
    }

    private void openWifi() {
        ShellUtil.execCommandNoWait(new String[]{"adb", "-s", connectAddress, "shell", "svc", "wifi", "enable"});
    }

    private boolean forceStop() {
        // TODO Auto-generated method stub
        String[] command = {GlobalConstants.ADB_COMMAND, "-s", connectAddress, "shell", "am", "force-stop", apkFile.getPackageName()};
        ShellUtil.CommandResult commandResult = ShellUtil.execCommand(command);
        return commandResult.isCommandSucceeded();
    }

    private static List<UiDumpModel> uiDumpModels;
    private static List<UiDumpModel> clickableUidumps;

    private static List<UiDumpModel> clickedUidumps;
    private static List<UiDumpModel> clickableUidumps1;
    private static List<UiDumpModel> clickableUidumps2;
    private static List<UiDumpModel> clickableUidumps3;

    private static List<UiDumpModel> currentUidumps;

    private static UiDumpModel uiDumpModel1;

    private static List<String> openedActivity;

    private boolean checkUITimes() {
        afterTime = System.currentTimeMillis();
        logger.info("当前已运行：" + (afterTime - beforeTime) / 1000);
        if ((afterTime - beforeTime) < threshold * 60 * 1000) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * auto check all UI
     */
    private void checkAllUI() throws InterruptedException {
        // TODO Auto-generated method stub
        if (startApp(false) && checkUITimes()) {
            service.refresh();
            uiDumpModels = service.getDumps();
            clickableUidumps = new ArrayList<>();
            currentUidumps = new ArrayList<>();

            clickedUidumps = new ArrayList<>();
            clickableUidumps1 = new ArrayList<>();
            clickableUidumps2 = new ArrayList<>();
            clickableUidumps3 = new ArrayList<>();
            if (!openedActivity.contains(getCurrentActivityName())) {
                openedActivity.add(getCurrentActivityName());
            }
            takePicShot(picShot);
            if (checkUITimes()) {
                loopUi();
            }
        }
    }

    private void loopUi() {
        // TODO Auto-generated method stub
        Collections.reverse(uiDumpModels);
        getMainClickableUI(uiDumpModels);

        reStartApp();
        waitForRefresh();

        service.refresh();
        waitForRefresh();
        uiDumpModels = service.getDumps();
        Collections.reverse(uiDumpModels);
        getMainClickableUI(uiDumpModels);

        if (checkUITimes()) {
            checkUi();
        }
    }

    private void checkUi() {
        // TODO Auto-generated method stub
        clickableUidumps1 = getClickableUI(service.getDumps());
        if (!openedActivity.contains(getCurrentActivityName())) {
            openedActivity.add(getCurrentActivityName());
        }
        if (checkUITimes()) {
            checkForOne();
        }
    }


    private void checkForOne() {
        // TODO Auto-generated method stub
        for (int i = 0; i < clickableUidumps1.size(); i++) {
            uiDumpModel1 = clickableUidumps1.get(i);
            if (!clickedUidumps.contains(uiDumpModel1) && checkUITimes()) {
                tap(uiDumpModel1.getCoordinate().getX(), uiDumpModel1.getCoordinate().getY());
                logger.info("第一层共" + clickableUidumps1.size() + "个控件");
                logger.info("点击了第一层的" + i + "个控件");
                addNew(uiDumpModel1);
                if (checkUITimes()) {
                    service.refresh();
                    currentUidumps.clear();
                    currentUidumps = service.getDumps();
                    currentUidumps = getClickableUI(currentUidumps);
                    if (compareCurrent(clickableUidumps1, currentUidumps)) {
                        logger.info("准备移除第一层的");
                        reStartApp();
                    } else {
                        logger.info("准备到第二层");
                        if (!openedActivity.contains(getCurrentActivityName())) {
                            openedActivity.add(getCurrentActivityName());
                        }
                        if (checkUITimes()) {
                            checkForTwo(uiDumpModel1);
                        }
                    }
                }
            }
        }
        logger.info("都结束了");
    }

    int count1 = 0;

    private void checkForTwo(UiDumpModel uiDumpModel1) {
        // TODO Auto-generated method stub
        forceStop();
        waitForRefresh();
        if (startApp(false)) {
            waitForRefresh();
            tap(uiDumpModel1.getCoordinate().getX(), uiDumpModel1.getCoordinate().getY());
        }
        if (checkUITimes()) {
            service.refresh();
            waitForRefresh();
            logger.info("检测到有第二界面，截图");
            takePicShot(picShot);
            clickableUidumps2 = getClickableUI(service.getDumps());
            logger.info("第二层有1：" + clickableUidumps2.size());

            clickableUidumps2.removeAll(clickableUidumps1);
            logger.info("第二层有2：" + clickableUidumps2.size());
            if (checkUITimes()) {
                checkForTwoOne(uiDumpModel1, clickableUidumps2);
            }
        }

        count1 = 0;
        logger.info("第二层循环结束，走到这里");
    }

    private void checkForTwoOne(UiDumpModel uiDumpModel1, List<UiDumpModel> uiDumpModels2) {
        // TODO Auto-generated method stub
        forceStop();
        if (startApp(false)) {
            waitForRefresh();
            tap(uiDumpModel1.getCoordinate().getX(), uiDumpModel1.getCoordinate().getY());
        }
        waitForRefresh();
        while (count1 < uiDumpModels2.size() && checkUITimes()) {
            if (!clickedUidumps.contains(uiDumpModels2.get(count1))) {
                UiDumpModel uiDumpModel2 = uiDumpModels2.get(count1);
                logger.info("点击第二层的：" + count1 + "个控件");
                if (!clickableUidumps.contains(uiDumpModel2) && checkUITimes()) {
                    tap(uiDumpModel2.getCoordinate().getX(), uiDumpModel2.getCoordinate().getY());

                    service.refresh();
                    waitForRefresh();
                    if (checkUITimes()) {
                        if (!openedActivity.contains(getCurrentActivityName())) {
                            openedActivity.add(getCurrentActivityName());
                        }
                        currentUidumps.clear();
                        currentUidumps = getClickableUI(service.getDumps());
                        addNew(uiDumpModel2);
                        if (compareCurrent(clickableUidumps2, currentUidumps)) {
                            logger.info("一样，继续");
                            count1 = count1 + 1;
                            checkForTwoOne(uiDumpModel1, clickableUidumps2);
                        } else {
                            logger.info("不一样哦");
                            logger.info("有第三层界面，截图");
                            takePicShot(picShot);
                            clickableUidumps3 = currentUidumps;
                            count1 = count1 + 1;
                        }
                    }

                }
                logger.info("count1：" + count1 + "  总数量：" + uiDumpModels2.size());
                if (count1 >= uiDumpModels2.size()) {
                    addNew(uiDumpModel1);
                }
                if (checkUITimes()) {
                    checkForTwoOne(uiDumpModel1, clickableUidumps2);
                }
            } else {
                count1++;
            }
        }
        logger.info("第二层的循环结束");
    }


    public String getCurrentActivityName() {
        String[] command = {GlobalConstants.ADB_COMMAND, "-s", connectAddress, "shell", "dumpsys", "activity | grep \"mFocusedActivity\""};
        ShellUtil.CommandResult commandResult = ShellUtil.execCommand(command);
        if (!StringUtil.isEmpty(commandResult.getResultMsg())) {
            return commandResult.getResultMsg().split(" ")[3];
        } else {
            return "";
        }
    }

    /**
     * 比对两个List，如果新List数量小与原List，返回false，如果不同元素大于两个，返回false，
     *
     * @param originalUIDumps
     * @param currentUidumps
     * @return
     */
    private boolean compareCurrent(List<UiDumpModel> originalUIDumps, List<UiDumpModel> currentUidumps) {
        int count = 0;
        if (currentUidumps.size() != originalUIDumps.size()) {
            return false;
        }
        for (int i = 0; i < currentUidumps.size(); i++) {
            UiDumpModel uiDumpModel = currentUidumps.get(i);
            if (!originalUIDumps.contains(uiDumpModel)) {
                count++;
            }
            if (count >= 1) {
                return false;
            }
        }
        return true;
    }

    private void addNew(UiDumpModel uiDumpModel) {
        if (!clickedUidumps.contains(uiDumpModel)) {
            clickedUidumps.add(uiDumpModel);
        }
    }

    /**
     * 获取可点击的UI
     *
     * @param list
     */
    private List<UiDumpModel> getClickableUI(List<UiDumpModel> list) {
        List<UiDumpModel> liss = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            UiDumpModel uiDumpModel = list.get(i);
            if (uiDumpModel.getClickable().contains("true") && uiDumpModel.getPackageName().equals(packageName)) {
                liss.add(uiDumpModel);
            }
        }

        logger.info("clickable:" + liss.toString());
        return liss;
    }

    private void waitForRefresh() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            logger.error(e.getMessage());
        }
    }

    private void reStartApp() {
        forceStop();
        startApp(false);
    }

    private void getMainClickableUI(List<UiDumpModel> list) {
        clickableUidumps.clear();
        for (int i = 0; i < list.size(); i++) {
            UiDumpModel uiDumpModel = list.get(i);
            if (uiDumpModel.getClickable().equals("true") && uiDumpModel.getPackageName().equals(packageName)) {
                clickableUidumps.add(uiDumpModel);
            }
        }
        uiDumpModels.clear();
        uiDumpModels.addAll(clickableUidumps);
    }

    /**
     * check view weather need to login
     */
    private void checkLogin() {
        logger.info("start check logining");
        if (!openedActivity.contains(getCurrentActivityName())) {
            openedActivity.add(getCurrentActivityName());
        }
        // TODO Auto-generated method stub
        if (true) {
            service.refresh();
            if (!openedActivity.contains(getCurrentActivityName())) {
                openedActivity.add(getCurrentActivityName());
            }
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            List<UiDumpModel> dumps = service.getDumps();
            logger.info("for start");
            for (int i = dumps.size() - 1; i >= 0; i--) {
                UiDumpModel uiDumpModel = dumps.get(i);
                logger.info("focusedActivity:"
                        + getCurrentActvity(connectAddress));
                logger.info("结果是：" + uiDumpModel.getText().toString().replaceAll(" ", "").contains("登录"));
                if (uiDumpModel.getText().contains("我的")
                        || uiDumpModel.getText().contains("个人中心")
                        || uiDumpModel.getText().replaceAll(" ", "").equals("登录")) {
                    logger.info("点击登录按钮");
                    tap(uiDumpModel.getCoordinate().getX(), uiDumpModel
                            .getCoordinate().getY());
                    if (!openedActivity.contains(getCurrentActivityName())) {
                        openedActivity.add(getCurrentActivityName());
                    }
                    try {
                        Thread.sleep(8000L);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    service.refresh();
                    logger.info("点击登录按钮后截图");
                    takePicShot(picShot);

                    try {
                        Thread.sleep(3000L);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    dumps.clear();
                    dumps = service.getDumps();
                    break;
                }
            }
            logger.info("登录页：" + dumps.toString());
            logger.info("step two");
            Collections.reverse(dumps);
            for (int i = 0; i < dumps.size(); i++) {
                logger.info("fengtiale:" + dumps.get(i).getText());
            }
            for (int i = 0; i < dumps.size(); i++) {
                UiDumpModel uiDumpModel = dumps.get(i);
                logger.info("focusedActivity:"
                        + getCurrentActvity(connectAddress));
                logger.info("step three");
                logger.info("fengtianle:" + uiDumpModel.getClassName());
                if (uiDumpModel.getClassName().toLowerCase()
                        .contains("edittext")) {
                    tap(uiDumpModel.getCoordinate().getX(), uiDumpModel
                            .getCoordinate().getY());
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (flag == 1) {
                        logger.info("输入密码:" + adbPassword);
                        inputText(adbPassword);
                        String[] unvisibleCommand = {GlobalConstants.ADB_COMMAND, "-s", connectAddress, "shell", "input", "keyevent", "4"};
                        ShellUtil.execCommand(unvisibleCommand);
                        logger.info("输入完密码后截图");
                        takePicShot(picShot);
                        flag++;
                    } else if (flag == 2) {
                        inputText(adbUserName);
                        logger.info("输入用户名" + adbUserName);
                        String[] unvisibleCommand = {GlobalConstants.ADB_COMMAND, "-s", connectAddress, "shell", "input", "keyevent", "4"};
                        ShellUtil.execCommand(unvisibleCommand);
                        logger.info("输入完用户名后截图");
                        takePicShot(picShot);
                        flag++;
                    }
                }
            }

            for (int i = 0; i < dumps.size(); i++) {
                UiDumpModel uiDumpModel = dumps.get(i);
                if (uiDumpModel.getClassName().toLowerCase().contains(
                        "button") || uiDumpModel.getClassName().toLowerCase().contains(
                        "textview") || uiDumpModel.getClickable().equals("true")) {
                    /*String[] unvisibleCommand = {
                            GlobalConstants.ADB_COMMAND, "-s",
                            connectAddress, "shell", "input", "keyevent",
                            "61"};
                    ShellUtil.execCommand(unvisibleCommand);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }*/
                    if (uiDumpModel.getText().trim().replaceAll(" ", "")
                            .equals("登录")
                            || uiDumpModel.getText().trim()
                            .replaceAll(" ", "").toLowerCase()
                            .equals("login")) {
                        logger.info("文本：" + uiDumpModel.getText().toString());
                        tap(uiDumpModel.getCoordinate().getX(), uiDumpModel
                                .getCoordinate().getY());
                        logger.info("正式点击登录按钮后截图");
                        takePicShot(picShot);
                        try {
                            Thread.sleep(5000L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        takePicShot(picShot);
                    }
                }
            }
        }
    }

    public String getCurrentActvity(String deviceSign) {
        String[] command = {GlobalConstants.ADB_COMMAND, "-s", deviceSign,
                "shell", "dumpsys", "activity | grep \"mFocusedActivity\""};
        ShellUtil.CommandResult commandResult = ShellUtil.execCommand(command);
        return commandResult.getResultMsg();
    }

    /**
     * 处理引导页.
     */
    protected void doWizardPage() {
        try {
            // 左滑5下.
            for (int i = 0; i < 6; i++) {
                rightSwipeUnLock();
                Thread.sleep(1000);
            }
            // 如果当前设备支持uiautomator。如果还处于引导页，找到第一个可点击控件。点击进入主画面.
            if (sdkVersion >= 16) {
                service.refresh();

                // 如果当前画面有viewpager，认为还处于引导页.
                Coordinate click = null;
                UiDumpModel viewPager = service
                        .findElementByClass(GlobalConstants.CLASS_TYPE_VIEW_PAGER);
                if (viewPager == null) {
                    viewPager = service
                            .findElementByClass(GlobalConstants.CLASS_TYPE_SCROLL_VIEW);
                }

                UiDumpModel clickBtn = service.findLastButton();
                logger.debug("viewPager: {}, clickBtn: {}", viewPager, clickBtn);
                if (clickBtn != null && viewPager != null) {
                    click = clickBtn.getCoordinate();
                    if (click != null) {
                        tap(click.getX(), click.getY());
                    }
                }
            }
        } catch (Exception e) {
            logger.warn(">> doWizardPage error {}.", e.getMessage(), e);
        }
    }

    private int picCount = 0;

    private void takePicShot(List<String> list) {
        logger.info("当前照片数为" + picCount);
        try {
            turnOnScreen(); // keep screen on.

            String pictureName = deviceRootPath + "n_" + picCount + ".png";
            String[] command = {
                    "sh",
                    "-c",
                    adbPath
                            + " -s "
                            + connectAddress
                            + " shell screencap -p | perl -pe 's/\\x0D\\x0A/\\x0A/g' > "
                            + pictureName};
            ShellUtil.CommandResult commandResult = ShellUtil
                    .execCommandNoLog(command);
            logger.info(device.getConnectAddress()
                            + " screencap start {}, save to file {}", picCount,
                    pictureName);
            if (commandResult.isCommandSucceeded()) {
                // logger.info(device.getConnectAddress() +
                // " screencap done {}, save to file {}", count, pictureName);
                list.add(StringUtil.removePrefix(pictureName,
                        removedPrefix));
                picCount++;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
